home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcl / src-16f.lha / code / print.lisp < prev    next >
Encoding:
Text File  |  1992-07-28  |  59.3 KB  |  1,754 lines

  1. ;;; -*- Log: code.log; Package: Lisp -*-
  2. ;;;
  3. ;;; **********************************************************************
  4. ;;; This code was written as part of the CMU Common Lisp project at
  5. ;;; Carnegie Mellon University, and has been placed in the public domain.
  6. ;;; If you want to use this code or any part of CMU Common Lisp, please contact
  7. ;;; Scott Fahlman or slisp-group@cs.cmu.edu.
  8. ;;;
  9. (ext:file-comment
  10.   "$Header: print.lisp,v 1.44.1.1 92/07/28 16:56:12 ram Exp $")
  11. ;;;
  12. ;;; **********************************************************************
  13. ;;;
  14. ;;; CMU Common Lisp printer.
  15. ;;;
  16. ;;; Written by Neal Feinberg, Bill Maddox, Steven Handerson, and Skef Wholey.
  17. ;;; Modified by various CMU Common Lisp maintainers.
  18. ;;;
  19.  
  20. (in-package "LISP")
  21.  
  22. (export '(*print-readably* *print-escape* *print-pretty* *print-circle*
  23.       *print-base* *print-radix* *print-case* *print-gensym* *print-level*
  24.       *print-length* *print-array* *print-lines* *print-right-margin*
  25.       *print-miser-width* *print-pprint-dispatch* with-standard-io-syntax
  26.       write prin1 print princ pprint
  27.       write-to-string prin1-to-string princ-to-string
  28.       print-unreadable-object))
  29.  
  30. (in-package "KERNEL")
  31. (export '(*current-level* *pretty-printer* output-object output-ugly-object
  32.       check-for-circularity handle-circularity descend-into
  33.       punt-if-too-long output-symbol-name))
  34.  
  35. (in-package "LISP")
  36.  
  37.  
  38.  
  39. ;;;; Exported printer control variables.
  40.  
  41. (defvar *print-readably* nil
  42.   "If true, all objects will printed readably.  If readably printing is
  43.   impossible, an error will be signalled.  This overrides the value of
  44.   *PRINT-ESCAPE*.")
  45. (defvar *print-escape* T
  46.   "Flag which indicates that slashification is on.  See the manual")
  47. (defvar *print-pretty* nil
  48.   "Flag which indicates that pretty printing is to be used")
  49. (defvar *print-base* 10.
  50.   "The output base for integers and rationals.")
  51. (defvar *print-radix* nil
  52.   "This flag requests to verify base when printing rationals.")
  53. (defvar *print-level* nil
  54.   "How many levels deep to print.  Unlimited if null.")
  55. (defvar *print-length* nil
  56.   "How many elements to print on each level.  Unlimited if null.")
  57. (defvar *print-circle* nil
  58.   "Whether to worry about circular list structures. See the manual.")
  59. (defvar *print-case* :upcase
  60.   "What kind of case the printer should use by default")
  61. (defvar *print-array* t
  62.   "Whether the array should print it's guts out")
  63. (defvar *print-gensym* t
  64.   "If true, symbols with no home package are printed with a #: prefix.
  65.   If false, no prefix is printed.")
  66. (defvar *print-lines* nil
  67.   "The maximum number of lines to print.  If NIL, unlimited.")
  68. (defvar *print-right-margin* nil
  69.   "The position of the right margin in ems.  If NIL, try to determine this
  70.    from the stream in use.")
  71. (defvar *print-miser-width* nil
  72.   "If the remaining space between the current column and the right margin
  73.    is less than this, then print using ``miser-style'' output.  Miser
  74.    style conditional newlines are turned on, and all indentations are
  75.    turned off.  If NIL, never use miser mode.")
  76. (defvar *print-pprint-dispatch* nil
  77.   "The pprint-dispatch-table that controls how to pretty print objects.  See
  78.    COPY-PPRINT-DISPATH, PPRINT-DISPATCH, and SET-PPRINT-DISPATCH.")
  79.  
  80. (defmacro with-standard-io-syntax (&body body)
  81.   "Bind the reader and printer control variables to values that enable READ
  82.    to reliably read the results of PRINT.  These values are:
  83.        *PACKAGE*            The COMMON-LISP-USER package
  84.        *PRINT-ARRAY*            T
  85.        *PRINT-BASE*            10
  86.        *PRINT-CASE*            :UPCASE
  87.        *PRINT-CIRCLE*            NIL
  88.        *PRINT-ESCAPE*            T
  89.        *PRINT-GENSYM*            T
  90.        *PRINT-LENGTH*            NIL
  91.        *PRINT-LEVEL*            NIL
  92.        *PRINT-LINES*            NIL
  93.        *PRINT-MISER-WIDTH*        NIL
  94.        *PRINT-PRETTY*            NIL
  95.        *PRINT-RADIX*            NIL
  96.        *PRINT-READABLY*            T
  97.        *PRINT-RIGHT-MARGIN*        NIL
  98.        *READ-BASE*            10
  99.        *READ-DEFAULT-FLOAT-FORMAT*     SINGLE-FLOAT
  100.        *READ-EVAL*            T
  101.        *READ-SUPPRESS*            NIL
  102.        *READTABLE*            the standard readtable."
  103.   `(%with-standard-io-syntax #'(lambda () ,@body)))
  104.  
  105. (defun %with-standard-io-syntax (function)
  106.   (let ((*package* (find-package "USER"))
  107.     (*print-array* t)
  108.     (*print-base* 10)
  109.     (*print-case* :upcase)
  110.     (*print-circle* nil)
  111.     (*print-escape* t)
  112.     (*print-gensym* t)
  113.     (*print-length* nil)
  114.     (*print-level* nil)
  115.     (*print-lines* nil)
  116.     (*print-miser-width* nil)
  117.     (*print-pretty* nil)
  118.     (*print-radix* nil)
  119.     (*print-readably* t)
  120.     (*print-right-margin* nil)
  121.     (*read-base* 10)
  122.     (*read-default-float-format* 'single-float)
  123.     (*read-eval* t)
  124.     (*read-suppress* nil)
  125.     (*readtable* std-lisp-readtable))
  126.     (funcall function)))
  127.  
  128.  
  129. ;;;; Routines to print objects.
  130.  
  131. (defun write (object &key
  132.              ((:stream stream) *standard-output*)
  133.              ((:escape *print-escape*) *print-escape*)
  134.              ((:radix *print-radix*) *print-radix*)
  135.              ((:base *print-base*) *print-base*)
  136.              ((:circle *print-circle*) *print-circle*)
  137.              ((:pretty *print-pretty*) *print-pretty*)
  138.              ((:level *print-level*) *print-level*)
  139.              ((:length *print-length*) *print-length*)
  140.              ((:case *print-case*) *print-case*)
  141.              ((:array *print-array*) *print-array*)
  142.              ((:gensym *print-gensym*) *print-gensym*)
  143.              ((:readably *print-readably*) *print-readably*)
  144.              ((:right-margin *print-right-margin*) 
  145.               *print-right-margin*)
  146.              ((:miser-width *print-miser-width*) 
  147.               *print-miser-width*)
  148.              ((:lines *print-lines*) *print-lines*)
  149.              ((:pprint-dispatch *print-pprint-dispatch*)
  150.               *print-pprint-dispatch*))
  151.   "Outputs OBJECT to the specified stream, defaulting to *standard-output*"
  152.   (output-object object (out-synonym-of stream))
  153.   object)
  154.  
  155. (defun prin1 (object &optional stream)
  156.   "Outputs a mostly READable printed representation of OBJECT on the specified
  157.   stream."
  158.   (let ((*print-escape* T))
  159.     (output-object object (out-synonym-of stream)))
  160.   object)
  161.  
  162. (defun princ (object &optional stream)
  163.   "Outputs an asthetic but not READable printed representation of OBJECT on the
  164.   specified stream."
  165.   (let ((*print-escape* NIL))
  166.     (output-object object (out-synonym-of stream)))
  167.   object)
  168.  
  169. (defun print (object &optional stream)
  170.   "Outputs a terpri, the mostly READable printed represenation of OBJECT, and 
  171.   space to the stream."
  172.   (let ((stream (out-synonym-of stream)))
  173.     (terpri stream)
  174.     (prin1 object stream)
  175.     (write-char #\space stream)
  176.     object))
  177.  
  178. (defun pprint (object &optional stream)
  179.   "Prettily outputs the Object preceded by a newline."
  180.   (let ((*print-pretty* t)
  181.     (*print-escape* t)
  182.     (stream (out-synonym-of stream)))
  183.     (terpri stream)
  184.     (output-object object stream))
  185.   (values))
  186.  
  187.  
  188. (defun write-to-string
  189.        (object &key
  190.            ((:escape *print-escape*) *print-escape*)
  191.            ((:radix *print-radix*) *print-radix*)
  192.            ((:base *print-base*) *print-base*)
  193.            ((:circle *print-circle*) *print-circle*)
  194.            ((:pretty *print-pretty*) *print-pretty*)
  195.            ((:level *print-level*) *print-level*)
  196.            ((:length *print-length*) *print-length*)
  197.            ((:case *print-case*) *print-case*)
  198.            ((:array *print-array*) *print-array*)
  199.            ((:gensym *print-gensym*) *print-gensym*)
  200.            ((:readably *print-readably*) *print-readably*)
  201.            ((:right-margin *print-right-margin*) *print-right-margin*)
  202.            ((:miser-width *print-miser-width*) *print-miser-width*)
  203.            ((:lines *print-lines*) *print-lines*)
  204.            ((:pprint-dispatch *print-pprint-dispatch*)
  205.         *print-pprint-dispatch*))
  206.   "Returns the printed representation of OBJECT as a string."
  207.   (stringify-object object))
  208.  
  209. (defun prin1-to-string (object)
  210.   "Returns the printed representation of OBJECT as a string with 
  211.    slashification on."
  212.   (stringify-object object t))
  213.  
  214. (defun princ-to-string (object)
  215.   "Returns the printed representation of OBJECT as a string with
  216.   slashification off."
  217.   (stringify-object object nil))
  218.  
  219. ;;; STRINGIFY-OBJECT -- Internal.
  220. ;;;
  221. ;;; This produces the printed representation of an object as a string.  The
  222. ;;; few ...-TO-STRING functions above call this.
  223. ;;;
  224. (defvar *string-output-streams* ())
  225. ;;;
  226. (defun stringify-object (object &optional (*print-escape* *print-escape*))
  227.   (let ((stream (if *string-output-streams*
  228.             (pop *string-output-streams*)
  229.             (make-string-output-stream))))
  230.     (setup-printer-state)
  231.     (output-object object stream)
  232.     (prog1
  233.     (get-output-stream-string stream)
  234.       (push stream *string-output-streams*))))
  235.  
  236.  
  237.  
  238. ;;;; PRINT-UNREADABLE-OBJECT macro
  239.  
  240. (defmacro print-unreadable-object ((object stream &key type identity)
  241.                    &body body)
  242.   `(%print-unreadable-object ,object ,stream ,type ,identity
  243.                  ,(if body
  244.                   `#'(lambda () ,@body)
  245.                   nil)))
  246.  
  247. (defun %print-unreadable-object (object stream type identity body)
  248.   (when *print-readably*
  249.     (error "~S cannot be printed readably." object))
  250.   (write-string "#<" stream)
  251.   (when type
  252.     (write (type-of object) :stream stream :circle nil
  253.        :level nil :length nil)
  254.     (when (or body identity)
  255.       (write-char #\space stream)))
  256.   (when body
  257.     (funcall body))
  258.   (when identity
  259.     (when body
  260.       (write-char #\space stream))
  261.     (write-char #\{ stream)
  262.     (write (get-lisp-obj-address object) :stream stream
  263.        :radix nil :base 16)
  264.     (write-char #\} stream))
  265.   (write-char #\> stream)
  266.   nil)
  267.  
  268.  
  269. ;;;; WHITESPACE-CHAR-P
  270.  
  271. ;;; This is used in other files, but is defined in this one for some reason.
  272.  
  273. (defun whitespace-char-p (char)
  274.   "Determines whether or not the character is considered whitespace."
  275.   (or (char= char #\space)
  276.       (char= char #\tab)
  277.       (char= char #\return)
  278.       (char= char #\linefeed)))
  279.  
  280.  
  281.  
  282. ;;;; Circularity detection stuff.
  283.  
  284. ;;; *CIRCULARITY-HASH-TABLE* -- internal.
  285. ;;;
  286. ;;; When *print-circle* is T, this gets bound to a hash table that (eventually)
  287. ;;; ends up with entries for every object printed.  When we are initially
  288. ;;; looking for circularities, we enter a T when we find an object for the
  289. ;;; first time, and a 0 when we encounter an object a second time around.
  290. ;;; When we are actually printing, the 0 entries get changed to the actual
  291. ;;; marker value when they are first printed.
  292. ;;; 
  293. (defvar *circularity-hash-table* nil)
  294.  
  295. ;;; *CIRCULARITY-COUNTER* -- internal.
  296. ;;;
  297. ;;; When NIL, we are just looking for circularities.  After we have found them
  298. ;;; all, this gets bound to 0.  Then whenever we need a new marker, it is
  299. ;;; incremented.
  300. ;;;
  301. (defvar *circularity-counter* nil)
  302.  
  303. ;;; CHECK-FOR-CIRCULARITY -- interface.
  304. ;;;
  305. (defun check-for-circularity (object &optional assign)
  306.   "Check to see if OBJECT is a circular reference, and return something non-NIL
  307.    if it is.  If ASSIGN is T, then the number to use in the #n= and #n# noise
  308.    is assigned at this time.  Note: CHECK-FOR-CIRCULARITY must be called
  309.    *EXACTLY* once with ASSIGN T, or the circularity detection noise will get
  310.    confused about when to use #n= and when to use #n#.  If this returns
  311.    non-NIL when ASSIGN is T, then you must call HANDLE-CIRCULARITY on it.
  312.    If you are not using this inside a WITH-CIRCULARITY-DETECTION, then you
  313.    have to be prepared to handle a return value of :INITIATE which means it
  314.    needs to initiate the circularity detection noise.  See the source for
  315.    info on how to do that."
  316.   (cond ((null *print-circle*)
  317.      ;; Don't bother, nobody cares.
  318.      nil)
  319.     ((null *circularity-hash-table*)
  320.      :initiate)
  321.     ((null *circularity-counter*)
  322.      (ecase (gethash object *circularity-hash-table*)
  323.        ((nil)
  324.         ;; First encounter.
  325.         (setf (gethash object *circularity-hash-table*) t)
  326.         ;; We need to keep looking.
  327.         nil)
  328.        ((t)
  329.         ;; Second encounter.
  330.         (setf (gethash object *circularity-hash-table*) 0)
  331.         ;; It's a circular reference.
  332.         t)
  333.        (0
  334.         ;; It's a circular reference.
  335.         t)))
  336.     (t
  337.      (let ((value (gethash object *circularity-hash-table*)))
  338.        (case value
  339.          ((nil t)
  340.           ;; If NIL, we found an object that wasn't there the first time
  341.           ;; around.  If T, exactly one occurance of this object appears.
  342.           ;; Either way, just print the thing without any special
  343.           ;; processing.  Note: you might argue that finding a new object
  344.           ;; means that something is broken, but this can happen.  If
  345.           ;; someone uses the ~@<...~:> format directive, it conses a
  346.           ;; new list each time though format (i.e. the &REST list), so
  347.           ;; we will have different cdrs.
  348.           nil)
  349.          (0
  350.           (if assign
  351.           (let ((value (incf *circularity-counter*)))
  352.             ;; First occurance of this object.  Set the counter.
  353.             (setf (gethash object *circularity-hash-table*) value)
  354.             value)
  355.           t))
  356.          (t
  357.           ;; Second or later occurance.
  358.           (- value)))))))
  359.  
  360. ;;; HANDLE-CIRCULARITY -- interface.
  361. ;;; 
  362. (defun handle-circularity (marker stream)
  363.   "Handle the results of CHECK-FOR-CIRCULARITY.  If this returns T then
  364.    you should go ahead and print the object.  If it returns NIL, then
  365.    you should blow it off."
  366.   (case marker
  367.     (:initiate
  368.      ;; Someone forgot to initiate circularity detection.
  369.      (let ((*print-circle* nil))
  370.        (error "Attempt to use CHECK-FOR-CIRCULARITY when circularity ~
  371.            checking has not been initiated.")))
  372.     ((t)
  373.      ;; It's a second (or later) reference to the object while we are
  374.      ;; just looking.  So don't bother groveling it again.
  375.      nil)
  376.     (t
  377.      (write-char #\# stream)
  378.      (let ((*print-base* 10) (*print-radix* nil))
  379.        (cond ((minusp marker)
  380.           (output-integer (- marker) stream)
  381.           (write-char #\# stream)
  382.           nil)
  383.          (t
  384.           (output-integer marker stream)
  385.           (write-char #\= stream)
  386.           t))))))
  387.  
  388.  
  389. ;;;; Level and Length abbreviations.
  390.  
  391. ;;; *CURRENT-LEVEL* -- interface.
  392. ;;; 
  393. (defvar *current-level* 0
  394.   "The current level we are printing at, to be compared against *PRINT-LEVEL*.
  395.    See the macro DESCEND-INTO for a handy interface to depth abbreviation.")
  396.  
  397. ;;; DESCEND-INTO -- interface.
  398. ;;; 
  399. (defmacro descend-into ((stream) &body body)
  400.   "Automatically handle *print-level* abbreviation.  If we are too deep, then
  401.    a # is printed to STREAM and BODY is ignored."
  402.   (let ((flet-name (gensym)))
  403.     `(flet ((,flet-name ()
  404.           ,@body))
  405.        (cond ((and (null *print-readably*)
  406.            *print-level*
  407.            (>= *current-level* *print-level*))
  408.           (write-char #\# ,stream))
  409.          (t
  410.           (let ((*current-level* (1+ *current-level*)))
  411.         (,flet-name)))))))
  412.  
  413. ;;; PUNT-IF-TOO-LONG -- interface.
  414. ;;; 
  415. (defmacro punt-if-too-long (index stream)
  416.   "Punt if INDEX is equal or larger then *PRINT-LENGTH* (and *PRINT-READABLY*
  417.    is NIL) by outputting \"...\" and returning from the block named NIL."
  418.   `(when (and (not *print-readably*)
  419.           *print-length*
  420.           (>= ,index *print-length*))
  421.      (write-string "..." ,stream)
  422.      (return)))
  423.  
  424.  
  425. ;;;; OUTPUT-OBJECT -- the main entry point.
  426.  
  427. ;;; *PRETTY-PRINTER* -- public.
  428. ;;; 
  429. (defvar *pretty-printer* nil
  430.   "The current pretty printer.  Should be either a function that takes two
  431.    arguments (the object and the stream) or NIL to indicate that there is
  432.    no pretty printer installed.")
  433.  
  434. ;;; OUTPUT-OBJECT -- interface.
  435. ;;; 
  436. (defun output-object (object stream)
  437.   "Output OBJECT to STREAM observing all printer control variables."
  438.   (labels ((print-it (stream)
  439.          (if *print-pretty*
  440.          (if *pretty-printer*
  441.              (funcall *pretty-printer* object stream)
  442.              (let ((*print-pretty* nil))
  443.                (output-ugly-object object stream)))
  444.          (output-ugly-object object stream)))
  445.        (check-it (stream)
  446.          (let ((marker (check-for-circularity object t)))
  447.            (case marker
  448.          (:initiate
  449.           (let ((*circularity-hash-table*
  450.              (make-hash-table :test #'eq)))
  451.             (check-it (make-broadcast-stream))
  452.             (let ((*circularity-counter* 0))
  453.               (check-it stream))))
  454.          ((nil)
  455.           (print-it stream))
  456.          (t
  457.           (when (handle-circularity marker stream)
  458.             (print-it stream)))))))
  459.     (cond ((or (not *print-circle*)
  460.            (numberp object)
  461.            (characterp object)
  462.            (and (symbolp object) (symbol-package object) t))
  463.        ;; If it a number, character, or interned symbol, we do not want
  464.        ;; to check for circularity/sharing.
  465.        (print-it stream))
  466.       ((or *circularity-hash-table*
  467.            (consp object)
  468.            (structurep object)
  469.            (typep object '(array t *)))
  470.        ;; If we have already started circularity detection, this object
  471.        ;; might be a sharded reference.  If we have not, then if it is
  472.        ;; a cons, a structure, or an array of element type t it might
  473.        ;; contain a circular reference to itself or multiple shared
  474.        ;; references.
  475.        (check-it stream))
  476.       (t
  477.        (print-it stream)))))
  478.  
  479. ;;; OUTPUT-UGLY-OBJECT -- interface.
  480. ;;; 
  481. (defun output-ugly-object (object stream)
  482.   "Output OBJECT to STREAM observing all printer control variables except
  483.    for *PRINT-PRETTY*.  Note: if *PRINT-PRETTY* is non-NIL, then the pretty
  484.    printer will be used for any components of OBJECT, just not for OBJECT
  485.    itself."
  486.   (typecase object
  487.     (fixnum
  488.      (output-integer object stream))
  489.     (list
  490.      (if (null object)
  491.      (output-symbol object stream)
  492.      (output-list object stream)))
  493.     (structure
  494.      (output-structure object stream))
  495.     (function
  496.      (if (and (fboundp 'funcallable-instance-p)
  497.           (funcallable-instance-p object))
  498.      (pcl:print-object object stream)
  499.      (output-function object stream)))
  500.     (symbol
  501.      (output-symbol object stream))
  502.     (number
  503.      (etypecase object
  504.        (integer
  505.     (output-integer object stream))
  506.        (float
  507.     (output-float object stream))
  508.        (ratio
  509.     (output-ratio object stream))
  510.        (ratio
  511.     (output-ratio object stream))
  512.        (complex
  513.     (output-complex object stream))))
  514.     (character
  515.      (output-character object stream))
  516.     (vector
  517.      (output-vector object stream))
  518.     (array
  519.      (output-array object stream))
  520.     (system-area-pointer
  521.      (output-sap object stream))
  522.     (weak-pointer
  523.      (output-weak-pointer object stream))
  524.     (lra
  525.      (output-lra object stream))
  526.     (code-component
  527.      (output-code-component object stream))
  528.     (fdefn
  529.      (output-fdefn object stream))
  530.     (t
  531.      (output-random object stream))))
  532.  
  533.  
  534. ;;;; Symbols.
  535.  
  536. ;;; Values of *PRINT-CASE* and (READTABLE-CASE *READTABLE*) the last time the
  537. ;;; printer was called.
  538. ;;;
  539. (defvar *previous-case* nil)
  540. (defvar *previous-readtable-case* nil)
  541.  
  542. ;;; This variable contains the current definition of one of three symbol
  543. ;;; printers.  SETUP-PRINTER-STATE sets this variable.
  544. ;;;
  545. (defvar *internal-symbol-output-function* nil)
  546.  
  547. ;;; SETUP-PRINTER-STATE -- Internal.
  548. ;;;
  549. ;;; This function sets the internal global symbol
  550. ;;; *internal-symbol-output-function* to the right function depending on the
  551. ;;; value of *print-case*.  See the manual for details.  The print buffer
  552. ;;; stream is also reset.
  553. ;;;
  554. (defun setup-printer-state ()
  555.   (unless (and (eq *print-case* *previous-case*)
  556.            (eq (readtable-case *readtable*) *previous-readtable-case*))
  557.     (setq *previous-case* *print-case*)
  558.     (setq *previous-readtable-case* (readtable-case *readtable*))
  559.     (unless (member *print-case* '(:upcase :downcase :capitalize))
  560.       (setq *print-case* :upcase)
  561.       (error "Invalid *PRINT-CASE* value: ~S" *previous-case*))
  562.     (unless (member *previous-readtable-case*
  563.             '(:upcase :downcase :invert :preserve))
  564.       (setf (readtable-case *readtable*) :upcase)
  565.       (error "Invalid READTABLE-CASE value: ~S" *previous-readtable-case*))
  566.  
  567.     (setq *internal-symbol-output-function*
  568.       (case *previous-readtable-case*
  569.         (:upcase
  570.          (case *print-case*
  571.            (:upcase #'output-preserve-symbol)
  572.            (:downcase #'output-lowercase-symbol)
  573.            (:capitalize #'output-capitalize-symbol)))
  574.         (:downcase
  575.          (case *print-case*
  576.            (:upcase #'output-uppercase-symbol)
  577.            (:downcase #'output-preserve-symbol)
  578.            (:capitalize #'output-capitalize-symbol)))
  579.         (:preserve #'output-preserve-symbol)
  580.         (:invert #'output-invert-symbol)))))
  581.  
  582. ;;; OUTPUT-QUOTED-SYMBOL-NAME  --  Internal
  583. ;;;
  584. ;;;    Out Pname (a symbol-name or package-name) surrounded with |'s, and with
  585. ;;; any embedded |'s or \'s escaped.
  586. ;;;
  587. (defun output-quoted-symbol-name (pname stream)
  588.   (write-char #\| stream)
  589.   (dotimes (index (length pname))
  590.     (let ((char (schar pname index)))
  591.       (when (or (char= char #\\) (char= char #\|))
  592.     (write-char #\\ stream))
  593.       (write-char char stream)))
  594.   (write-char #\| stream))
  595.  
  596. (defun output-symbol (object stream)
  597.   (if (or *print-escape* *print-readably*)
  598.       (let ((package (symbol-package object))
  599.         (name (symbol-name object)))
  600.     (cond
  601.      ;; If the symbol's home package is the current one, then a
  602.      ;; prefix is never necessary.
  603.      ((eq package *package*))
  604.      ;; If the symbol is in the keyword package, output a colon.
  605.      ((eq package *keyword-package*)
  606.       (write-char #\: stream))
  607.      ;; Uninterned symbols print with a leading #:.
  608.      ((null package)
  609.       (when (or *print-gensym* *print-readably*)
  610.         (write-string "#:" stream)))
  611.      (t
  612.       (multiple-value-bind (symbol accessible)
  613.                    (find-symbol name *package*)
  614.         ;; If we can find the symbol by looking it up, it need not be
  615.         ;; qualified.  This can happen if the symbol has been inherited
  616.         ;; from a package other than its home package.
  617.         (unless (and accessible (eq symbol object))
  618.           (output-symbol-name (package-name package) stream)
  619.           (multiple-value-bind (symbol externalp)
  620.                    (find-external-symbol name package)
  621.         (declare (ignore symbol))
  622.         (if externalp
  623.             (write-char #\: stream)
  624.             (write-string "::" stream)))))))
  625.     (output-symbol-name name stream))
  626.       (output-symbol-name (symbol-name object) stream nil)))
  627.         
  628. ;;; OUTPUT-SYMBOL-NAME -- internal interface.
  629. ;;;
  630. ;;; Output the string NAME as if it were a symbol name.  In other words,
  631. ;;; diddle it's case according to *print-case* and readtable-case.
  632. ;;; 
  633. (defun output-symbol-name (name stream &optional (maybe-quote t))
  634.   (declare (type simple-base-string name))
  635.   (setup-printer-state)
  636.   (if (and maybe-quote (symbol-quotep name))
  637.       (output-quoted-symbol-name name stream)
  638.       (funcall *internal-symbol-output-function* name stream)))
  639.  
  640.  
  641. ;;;; Escaping symbols:
  642.  
  643. ;;;    When we print symbols we have to figure out if they need to be
  644. ;;; printed with escape characters.  This isn't a whole lot easier than
  645. ;;; reading symbols in the first place.
  646. ;;;
  647. ;;; For each character, the value of the corresponding element is a fixnum with
  648. ;;; bits set corresponding to attributes that the character has.  At characters
  649. ;;; have at least one bit set, so we can search for any character with a
  650. ;;; positive test.
  651. ;;;
  652. (defvar character-attributes
  653.   (make-array char-code-limit :element-type '(unsigned-byte 16)
  654.           :initial-element 0))
  655. ;;;
  656. (declaim (type (simple-array (unsigned-byte 16) (#.char-code-limit))
  657.            character-attributes))
  658.  
  659. (eval-when (compile load eval)
  660.  
  661. ;;; Constants which are a bit-mask for each interesting character attribute.
  662. ;;;
  663. (defconstant other-attribute        (ash 1 0)) ; Anything else legal.
  664. (defconstant number-attribute        (ash 1 1)) ; A numeric digit.
  665. (defconstant uppercase-attribute     (ash 1 2)) ; An uppercase letter.
  666. (defconstant lowercase-attribute     (ash 1 3)) ; A lowercase letter.
  667. (defconstant sign-attribute        (ash 1 4)) ; +-
  668. (defconstant extension-attribute     (ash 1 5)) ; ^_
  669. (defconstant dot-attribute         (ash 1 6)) ; .
  670. (defconstant slash-attribute        (ash 1 7)) ; /
  671. (defconstant funny-attribute        (ash 1 8)) ; Anything illegal.
  672.  
  673. ;;; LETTER-ATTRIBUTE is a local of SYMBOL-QUOTEP.  It matches letters that
  674. ;;; don't need to be escaped (according to READTABLE-CASE.)
  675. ;;;
  676. (defconstant attribute-names
  677.   `((number . number-attribute) (lowercase . lowercase-attribute)
  678.     (uppercase . uppercase-attribute) (letter . letter-attribute)
  679.     (sign . sign-attribute) (extension . extension-attribute)
  680.     (dot . dot-attribute) (slash . slash-attribute)
  681.     (other . other-attribute) (funny . funny-attribute)))
  682.  
  683. ); Eval-When (compile load eval)
  684.  
  685. (flet ((set-bit (char bit)
  686.      (let ((code (char-code char)))
  687.        (setf (aref character-attributes code)
  688.          (logior bit (aref character-attributes code))))))
  689.  
  690.   (dolist (char '(#\! #\@ #\$ #\% #\& #\* #\= #\~ #\[ #\] #\{ #\}
  691.           #\? #\< #\>))
  692.     (set-bit char other-attribute))
  693.  
  694.   (dotimes (i 10)
  695.     (set-bit (digit-char i) number-attribute))
  696.  
  697.   (do ((code (char-code #\A) (1+ code))
  698.        (end (char-code #\Z)))
  699.       ((> code end))
  700.     (declare (fixnum code end))
  701.     (set-bit (code-char code) uppercase-attribute)
  702.     (set-bit (char-downcase (code-char code)) lowercase-attribute))
  703.  
  704.   (set-bit #\- sign-attribute)
  705.   (set-bit #\+ sign-attribute)
  706.   (set-bit #\^ extension-attribute)
  707.   (set-bit #\_ extension-attribute)
  708.   (set-bit #\. dot-attribute)
  709.   (set-bit #\/ slash-attribute)
  710.  
  711.   ;; Make anything not explicitly allowed funny...
  712.   (dotimes (i char-code-limit)
  713.     (when (zerop (aref character-attributes i))
  714.       (setf (aref character-attributes i) funny-attribute))))
  715.  
  716. ;;; For each character, the value of the corresponding element is the lowest
  717. ;;; base in which that character is a digit.
  718. ;;;
  719. (defvar digit-bases
  720.   (make-array char-code-limit :element-type '(unsigned-byte 8)
  721.           :initial-element 36))
  722. ;;;
  723. (declaim (type (simple-array (unsigned-byte 8) (#.char-code-limit))
  724.            digit-bases))
  725.  
  726. (dotimes (i 36)
  727.   (let ((char (digit-char i 36)))
  728.     (setf (aref digit-bases (char-code char)) i)))
  729.  
  730.  
  731. ;;; SYMBOL-QUOTEP  --  Internal
  732. ;;;
  733. ;;;    A FSM-like thingie that determines whether a symbol is a potential
  734. ;;; number or has evil characters in it.
  735. ;;;
  736. (defun symbol-quotep (name)
  737.   (declare (simple-string name))
  738.   (macrolet ((advance (tag &optional (at-end t))
  739.            `(progn
  740.          (when (= index len)
  741.            ,(if at-end '(go TEST-SIGN) '(return nil)))
  742.          (setq current (schar name index)
  743.                code (char-code current)
  744.                bits (aref attributes code))
  745.          (incf index)
  746.          (go ,tag)))
  747.          (test (&rest attributes)
  748.         `(not (zerop
  749.                (the fixnum
  750.                 (logand
  751.                  (logior ,@(mapcar
  752.                     #'(lambda (x)
  753.                         (or (cdr (assoc x attribute-names))
  754.                         (error "Blast!")))
  755.                     attributes))
  756.                  bits)))))
  757.          (digitp ()
  758.            `(< (the fixnum (aref bases code)) base)))
  759.  
  760.     (prog ((len (length name))
  761.        (attributes character-attributes)
  762.        (bases digit-bases)
  763.        (base *print-base*)
  764.        (letter-attribute
  765.         (case (readtable-case *readtable*)
  766.           (:upcase uppercase-attribute)
  767.           (:downcase lowercase-attribute)
  768.           (t (logior lowercase-attribute uppercase-attribute))))
  769.        (index 0)
  770.        (bits 0)
  771.        (code 0)
  772.        current)
  773.       (declare (fixnum len base index bits code))
  774.       (advance START t)
  775.  
  776.      TEST-SIGN ; At end, see if it is a sign...
  777.       (return (not (test sign)))
  778.  
  779.      OTHER ; Not potential number, see if funny chars...
  780.       (let ((mask (logxor (logior lowercase-attribute uppercase-attribute
  781.                   funny-attribute)
  782.               letter-attribute)))
  783.     (do ((i (1- index) (1+ i)))
  784.         ((= i len) (return-from symbol-quotep nil))
  785.       (unless (zerop (logand (aref attributes (char-code (schar name i)))
  786.                  mask))
  787.         (return-from symbol-quotep t))))
  788.  
  789.      START
  790.       (when (digitp)
  791.     (if (test letter)
  792.         (advance LAST-DIGIT-ALPHA)
  793.         (advance DIGIT)))
  794.       (when (test letter number other slash) (advance OTHER nil))
  795.       (when (char= current #\.) (advance DOT-FOUND))
  796.       (when (test sign extension) (advance START-STUFF nil))
  797.       (return t)
  798.           
  799.      DOT-FOUND ; Leading dots...
  800.       (when (test letter) (advance START-DOT-MARKER nil))
  801.       (when (digitp) (advance DOT-DIGIT))
  802.       (when (test number other) (advance OTHER nil))
  803.       (when (test extension slash sign) (advance START-DOT-STUFF nil))
  804.       (when (char= current #\.) (advance DOT-FOUND))
  805.       (return t)
  806.  
  807.      START-STUFF ; Leading stuff before any dot or digit.
  808.       (when (digitp)
  809.     (if (test letter)
  810.         (advance LAST-DIGIT-ALPHA)
  811.         (advance DIGIT)))
  812.       (when (test number other) (advance OTHER nil))
  813.       (when (test letter) (advance START-MARKER nil))
  814.       (when (char= current #\.) (advance START-DOT-STUFF nil))
  815.       (when (test sign extension slash) (advance START-STUFF nil))
  816.       (return t)
  817.  
  818.      START-MARKER ; Number marker in leading stuff...
  819.       (when (test letter) (advance OTHER nil))
  820.       (go START-STUFF)
  821.  
  822.      START-DOT-STUFF ; Leading stuff containing dot w/o digit...
  823.       (when (test letter) (advance START-DOT-STUFF nil))
  824.       (when (digitp) (advance DOT-DIGIT))
  825.       (when (test sign extension dot slash) (advance START-DOT-STUFF nil))
  826.       (when (test number other) (advance OTHER nil))
  827.       (return t)
  828.  
  829.      START-DOT-MARKER ; Number marker in leading stuff w/ dot..
  830.       ;; Leading stuff containing dot w/o digit followed by letter...
  831.       (when (test letter) (advance OTHER nil))
  832.       (go START-DOT-STUFF)
  833.  
  834.      DOT-DIGIT ; In a thing with dots...
  835.       (when (test letter) (advance DOT-MARKER))
  836.       (when (digitp) (advance DOT-DIGIT))
  837.       (when (test number other) (advance OTHER nil))
  838.       (when (test sign extension dot slash) (advance DOT-DIGIT))
  839.       (return t)
  840.  
  841.      DOT-MARKER ; Number maker in number with dot...
  842.       (when (test letter) (advance OTHER nil))
  843.       (go DOT-DIGIT)
  844.  
  845.      LAST-DIGIT-ALPHA ; Previous char is a letter digit...
  846.       (when (or (digitp) (test sign slash))
  847.     (advance ALPHA-DIGIT))
  848.       (when (test letter number other dot) (advance OTHER nil))
  849.       (return t)
  850.       
  851.      ALPHA-DIGIT ; Seen a digit which is a letter...
  852.       (when (or (digitp) (test sign slash))
  853.     (if (test letter)
  854.         (advance LAST-DIGIT-ALPHA)
  855.         (advance ALPHA-DIGIT)))
  856.       (when (test letter) (advance ALPHA-MARKER))
  857.       (when (test number other dot) (advance OTHER nil))
  858.       (return t)
  859.  
  860.      ALPHA-MARKER ; Number marker in number with alpha digit...
  861.       (when (test letter) (advance OTHER nil))
  862.       (go ALPHA-DIGIT)
  863.  
  864.      DIGIT ; Seen only real numeric digits...
  865.       (when (digitp)
  866.     (if (test letter)
  867.         (advance ALPHA-DIGIT)
  868.         (advance DIGIT)))
  869.       (when (test number other) (advance OTHER nil))
  870.       (when (test letter) (advance MARKER)) 
  871.       (when (test extension slash sign) (advance DIGIT))
  872.       (when (char= current #\.) (advance DOT-DIGIT))
  873.       (return t)
  874.  
  875.      MARKER ; Number marker in a numeric number...
  876.       (when (test letter) (advance OTHER nil))
  877.       (go DIGIT))))
  878.  
  879.  
  880. ;;;; *INTERNAL-SYMBOL-OUTPUT-FUNCTION*
  881. ;;;
  882. ;;; Case hackery.  These functions are stored in
  883. ;;; *INTERNAL-SYMBOL-OUTPUT-FUNCTION* according to the values of *PRINT-CASE*
  884. ;;; and READTABLE-CASE.
  885. ;;;
  886.  
  887. ;; Called when:
  888. ;; READTABLE-CASE    *PRINT-CASE*
  889. ;; :UPCASE        :UPCASE
  890. ;; :DOWNCASE        :DOWNCASE
  891. ;; :PRESERVE        any
  892. (defun output-preserve-symbol (pname stream)
  893.   (declare (simple-string pname))
  894.   (write-string pname stream))
  895.  
  896. ;; Called when:
  897. ;; READTABLE-CASE    *PRINT-CASE*
  898. ;; :UPCASE        :DOWNCASE
  899. (defun output-lowercase-symbol (pname stream)
  900.   (declare (simple-string pname))
  901.   (dotimes (index (length pname))
  902.     (let ((char (schar pname index)))
  903.       (write-char (char-downcase char) stream))))
  904.  
  905. ;; Called when:
  906. ;; READTABLE-CASE    *PRINT-CASE*
  907. ;; :DOWNCASE        :UPCASE
  908. (defun output-uppercase-symbol (pname stream)
  909.   (declare (simple-string pname))
  910.   (dotimes (index (length pname))
  911.     (let ((char (schar pname index)))
  912.       (write-char (char-upcase char) stream))))
  913.  
  914. ;; Called when:
  915. ;; READTABLE-CASE    *PRINT-CASE*
  916. ;; :UPCASE        :CAPITALIZE
  917. ;; :DOWNCASE        :CAPITALIZE
  918. ;;
  919. (defun output-capitalize-symbol (pname stream)
  920.   (declare (simple-string pname))
  921.   (let ((prev-not-alpha t)
  922.     (up (eq (readtable-case *readtable*) :upcase)))
  923.     (dotimes (i (length pname))
  924.       (let ((char (char pname i)))
  925.     (write-char (if up
  926.             (if (or prev-not-alpha (lower-case-p char))
  927.                 char
  928.                 (char-downcase char))
  929.             (if prev-not-alpha
  930.                 (char-upcase char)
  931.                 char))
  932.             stream)
  933.     (setq prev-not-alpha (not (alpha-char-p char)))))))
  934.  
  935. ;; Called when:
  936. ;; READTABLE-CASE    *PRINT-CASE*
  937. ;; :INVERT        any
  938. (defun output-invert-symbol (pname stream)
  939.   (declare (simple-string pname))
  940.   (let ((all-upper t)
  941.     (all-lower t))
  942.     (dotimes (i (length pname))
  943.       (let ((ch (schar pname i)))
  944.     (when (both-case-p ch)
  945.       (if (upper-case-p ch)
  946.           (setq all-lower nil)
  947.           (setq all-upper nil)))))
  948.     (cond (all-upper (output-lowercase-symbol pname stream))
  949.       (all-lower (output-uppercase-symbol pname stream))
  950.       (t
  951.        (write-string pname stream)))))
  952.  
  953.  
  954. #|
  955. (defun test1 ()
  956.   (let ((*readtable* (copy-readtable nil)))
  957.     (format t "READTABLE-CASE  Input   Symbol-name~@
  958.            ----------------------------------~%")
  959.     (dolist (readtable-case '(:upcase :downcase :preserve :invert))
  960.       (setf (readtable-case *readtable*) readtable-case)
  961.       (dolist (input '("ZEBRA" "Zebra" "zebra"))
  962.     (format t "~&:~A~16T~A~24T~A"
  963.         (string-upcase readtable-case)
  964.         input
  965.         (symbol-name (read-from-string input)))))))
  966.  
  967. (defun test2 ()
  968.   (let ((*readtable* (copy-readtable nil)))
  969.     (format t "READTABLE-CASE  *PRINT-CASE*  Symbol-name  Output  Princ~@
  970.            --------------------------------------------------------~%")
  971.     (dolist (readtable-case '(:upcase :downcase :preserve :invert))
  972.       (setf (readtable-case *readtable*) readtable-case)
  973.       (dolist (*print-case* '(:upcase :downcase :capitalize))
  974.     (dolist (symbol '(|ZEBRA| |Zebra| |zebra|))
  975.       (format t "~&:~A~15T:~A~29T~A~42T~A~50T~A"
  976.           (string-upcase readtable-case)
  977.           (string-upcase *print-case*)
  978.           (symbol-name symbol)
  979.           (prin1-to-string symbol)
  980.           (princ-to-string symbol)))))))
  981.  
  982. |#
  983.  
  984. ;;;; Recursive objects.
  985.  
  986. (defun output-list (list stream)
  987.   (descend-into (stream)
  988.     (write-char #\( stream)
  989.     (let ((length 0)
  990.       (list list))
  991.       (loop
  992.     (punt-if-too-long length stream)
  993.     (output-object (pop list) stream)
  994.     (unless list
  995.       (return))
  996.     (when (or (atom list) (check-for-circularity list))
  997.       (write-string " . " stream)
  998.       (output-object list stream)
  999.       (return))
  1000.     (write-char #\space stream)
  1001.     (incf length)))
  1002.     (write-char #\) stream)))
  1003.  
  1004.  
  1005. (defun output-vector (vector stream)
  1006.   (declare (vector vector))
  1007.   (cond ((stringp vector)
  1008.      (if (or *print-escape* *print-readably*)
  1009.          (quote-string vector stream)
  1010.          (write-string vector stream)))
  1011.     ((not (or *print-array* *print-readably*))
  1012.      (output-terse-array vector stream))
  1013.     ((bit-vector-p vector)
  1014.      (write-string "#*" stream)
  1015.      (dotimes (i (length vector))
  1016.        (output-object (aref vector i) stream)))
  1017.     (t
  1018.      (when (and *print-readably*
  1019.             (not (eq (array-element-type vector) 't)))
  1020.        (error "Cannot print ~S in a readable format." vector))
  1021.      (descend-into (stream)
  1022.        (write-string "#(" stream)
  1023.        (dotimes (i (length vector))
  1024.          (unless (zerop i)
  1025.            (write-char #\space stream))
  1026.          (punt-if-too-long i stream)
  1027.          (output-object (aref vector i) stream))
  1028.        (write-string ")" stream)))))
  1029.  
  1030. ;;; QUOTE-STRING -- Internal.
  1031. ;;;
  1032. ;;; This function outputs a string quoting characters sufficiently, so someone
  1033. ;;; can read it in again.  Basically, put a slash in front of an character
  1034. ;;; satisfying FROB.
  1035. ;;;
  1036. (defun quote-string (string stream)
  1037.   (macrolet ((frob (char)
  1038.            ;; Probably should look at readtable, but just do this for now.
  1039.            `(or (char= ,char #\\)
  1040.             (char= ,char #\"))))
  1041.     (write-char #\" stream)
  1042.     (with-array-data ((data string) (start) (end))
  1043.       (do ((index start (1+ index)))
  1044.       ((>= index end))
  1045.     (let ((char (schar data index)))
  1046.       (when (frob char) (write-char #\\ stream))
  1047.       (write-char char stream))))
  1048.     (write-char #\" stream)))
  1049.  
  1050. (defun output-array (array stream)
  1051.   "Outputs the printed representation of any array in either the #< or #A
  1052.    form."
  1053.   (if (or *print-array* *print-readably*)
  1054.       (output-array-guts array stream)
  1055.       (output-terse-array array stream)))
  1056.  
  1057. ;;; Master function for outputing the #A form of an array
  1058. ;;;
  1059. (defun output-array-guts (array stream)
  1060.   (when (and *print-readably*
  1061.          (not (eq (array-element-type array) t)))
  1062.     (error "Arrays of element-type ~S cannot be printed readably."
  1063.        (array-element-type array)))
  1064.   (write-char #\# stream)
  1065.   (let ((*print-base* 10))
  1066.     (output-integer (array-rank array) stream))
  1067.   (write-char #\A stream)
  1068.   (with-array-data ((data array) (start) (end))
  1069.     (declare (ignore end))
  1070.     (sub-output-array-guts data (array-dimensions array) stream start)))
  1071.  
  1072. (defun sub-output-array-guts (array dimensions stream index)
  1073.   (declare (simple-vector array) (fixnum index))
  1074.   (cond ((null dimensions)
  1075.      (output-object (svref array index) stream))
  1076.     (t
  1077.      (descend-into (stream)
  1078.        (write-char #\( stream)
  1079.        (let* ((dimension (car dimensions))
  1080.           (dimensions (cdr dimensions))
  1081.           (count (reduce #'* dimensions)))
  1082.          (dotimes (i dimension)
  1083.            (unless (zerop i)
  1084.          (write-char #\space stream))
  1085.            (punt-if-too-long i stream)
  1086.            (sub-output-array-guts array dimensions stream index)
  1087.            (incf index count)))
  1088.        (write-char #\) stream)))))
  1089.  
  1090. ;;; Used to output the #< form of any array.
  1091. ;;;
  1092. (defun output-terse-array (array stream)
  1093.   (let ((*print-level* nil)
  1094.     (*print-length* nil))
  1095.     (print-unreadable-object (array stream :type t :identity t))))
  1096.  
  1097.  
  1098. ;;; Structure Printing.  These days we can always pass the buck to the
  1099. ;;; Defstruct code.
  1100.  
  1101. (defun output-structure (structure stream)
  1102.   (funcall (or (info type printer (structure-ref structure 0))
  1103.            #'c::default-structure-print)
  1104.        structure stream *current-level*))
  1105.  
  1106.  
  1107. ;;;; Integer, ratio, and complex printing.  (i.e. everything but floats)
  1108.  
  1109. (defun output-integer (integer stream)
  1110.   (unless (and (fixnump *print-base*)
  1111.            (< 1 *print-base* 37))
  1112.     (let ((obase *print-base*))
  1113.       (setq *print-base* 10.)
  1114.       (error "~A is not a reasonable value for *Print-Base*." obase)))
  1115.   (when (and (not (= *print-base* 10.))
  1116.          *print-radix*)
  1117.     ;; First print leading base information, if any.
  1118.     (write-char #\# stream)
  1119.     (write-char (case *print-base*
  1120.           (2.  #\b)
  1121.           (8.  #\o)
  1122.           (16. #\x)
  1123.           (T (let ((fixbase *print-base*)
  1124.                (*print-base* 10.)
  1125.                (*print-radix* ()))
  1126.                (sub-output-integer fixbase stream))
  1127.              #\r))
  1128.         stream))
  1129.   ;; Then output a minus sign if the number is negative, then output
  1130.   ;; the absolute value of the number.
  1131.   (cond ((bignump integer) (print-bignum integer stream))
  1132.     ((< integer 0)
  1133.      (write-char #\- stream)
  1134.      (sub-output-integer (- integer) stream))
  1135.     (t
  1136.      (sub-output-integer integer stream)))
  1137.   ;; Print any trailing base information, if any.
  1138.   (if (and (= *print-base* 10.) *print-radix*)
  1139.       (write-char #\. stream)))
  1140.  
  1141. (defun sub-output-integer (integer stream)
  1142.   (let ((quotient ())
  1143.     (remainder ()))
  1144.     ;; Recurse until you have all the digits pushed on the stack.
  1145.     (if (not (zerop (multiple-value-setq (quotient remainder)
  1146.               (truncate integer *print-base*))))
  1147.     (sub-output-integer quotient stream))
  1148.     ;; Then as each recursive call unwinds, turn the digit (in remainder) 
  1149.     ;; into a character and output the character.
  1150.     (write-char (code-char (if (and (> remainder 9.)
  1151.                     (> *print-base* 10.))
  1152.                    (+ (char-code #\A) (- remainder 10.))
  1153.                    (+ (char-code #\0) remainder)))
  1154.         stream)))
  1155.  
  1156. ;;;; Bignum printing
  1157.  
  1158. ;;; Written by Steven Handerson
  1159. ;;;  (based on Skef's idea)
  1160. ;;;
  1161. ;;; Rewritten to remove assumptions about the length of fixnums for the
  1162. ;;; MIPS port by William Lott.
  1163. ;;; 
  1164.  
  1165. ;;; *BASE-POWER* holds the number that we keep dividing into the bignum for
  1166. ;;; each *print-base*.  We want this number as close to *most-positive-fixnum*
  1167. ;;; as possible, i.e. (floor (log most-positive-fixnum *print-base*)).
  1168. ;;; 
  1169. (defparameter *base-power* (make-array 37 :initial-element nil))
  1170.  
  1171. ;;; *FIXNUM-POWER--1* holds the number of digits for each *print-base* that
  1172. ;;; fit in the corresponding *base-power*.
  1173. ;;; 
  1174. (defparameter *fixnum-power--1* (make-array 37 :initial-element nil))
  1175.  
  1176. ;;; PRINT-BIGNUM -- internal.
  1177. ;;;
  1178. ;;; Print the bignum to the stream.  We first generate the correct value for
  1179. ;;; *base-power* and *fixnum-power--1* if we have not already.  Then we call
  1180. ;;; bignum-print-aux to do the printing.
  1181. ;;; 
  1182. (defun print-bignum (big stream)
  1183.   (unless (aref *base-power* *print-base*)
  1184.     (do ((power-1 -1 (1+ power-1))
  1185.      (new-divisor *print-base* (* new-divisor *print-base*))
  1186.      (divisor 1 new-divisor))
  1187.     ((not (fixnump new-divisor))
  1188.      (setf (aref *base-power* *print-base*) divisor)
  1189.      (setf (aref *fixnum-power--1* *print-base*) power-1))))
  1190.   (bignum-print-aux (cond ((minusp big)
  1191.                (write-char #\- stream)
  1192.                (- big))
  1193.               (t big))
  1194.             (aref *base-power* *print-base*)
  1195.             (aref *fixnum-power--1* *print-base*)
  1196.             stream)
  1197.   big)
  1198.  
  1199. ;;; BIGNUM-PRINT-AUX -- internal.
  1200. ;;;
  1201. (defun bignum-print-aux (big divisor power-1 stream)
  1202.   (multiple-value-bind (newbig fix) (truncate big divisor)
  1203.     (if (fixnump newbig)
  1204.     (sub-output-integer newbig stream)
  1205.     (bignum-print-aux newbig divisor power-1 stream))
  1206.     (do ((zeros power-1 (1- zeros))
  1207.      (base-power *print-base* (* base-power *print-base*)))
  1208.     ((> base-power fix)
  1209.      (dotimes (i zeros) (write-char #\0 stream))
  1210.      (sub-output-integer fix stream)))))
  1211.  
  1212.  
  1213. (defun output-ratio (ratio stream)
  1214.   (when *print-radix*
  1215.     (write-char #\# stream)
  1216.     (case *print-base*
  1217.       (2 (write-char #\b stream))
  1218.       (8 (write-char #\o stream))
  1219.       (16 (write-char #\x stream))
  1220.       (t (write *print-base* :stream stream :radix nil :base 10)))
  1221.     (write-char #\r stream))
  1222.   (let ((*print-radix* nil))
  1223.     (output-integer (numerator ratio) stream)
  1224.     (write-char #\/ stream)
  1225.     (output-integer (denominator ratio) stream)))
  1226.  
  1227. (defun output-complex (complex stream)
  1228.   (write-string "#C(" stream)
  1229.   (output-object (realpart complex) stream)
  1230.   (write-char #\space stream)
  1231.   (output-object (imagpart complex) stream)
  1232.   (write-char #\) stream))
  1233.  
  1234.  
  1235. ;;;; Float printing.
  1236.  
  1237. ;;;
  1238. ;;;  Written by Bill Maddox
  1239. ;;;
  1240. ;;;
  1241. ;;;
  1242. ;;; FLONUM-TO-STRING (and its subsidiary function FLOAT-STRING) does most of 
  1243. ;;; the work for all printing of floating point numbers in the printer and in
  1244. ;;; FORMAT.  It converts a floating point number to a string in a free or 
  1245. ;;; fixed format with no exponent.  The interpretation of the arguments is as 
  1246. ;;; follows:
  1247. ;;;
  1248. ;;;     X        - The floating point number to convert, which must not be
  1249. ;;;                negative.
  1250. ;;;     WIDTH    - The preferred field width, used to determine the number
  1251. ;;;                of fraction digits to produce if the FDIGITS parameter
  1252. ;;;                is unspecified or NIL.  If the non-fraction digits and the
  1253. ;;;                decimal point alone exceed this width, no fraction digits
  1254. ;;;                will be produced unless a non-NIL value of FDIGITS has been
  1255. ;;;                specified.  Field overflow is not considerd an error at this
  1256. ;;;                level.
  1257. ;;;     FDIGITS  - The number of fractional digits to produce. Insignificant
  1258. ;;;                trailing zeroes may be introduced as needed.  May be
  1259. ;;;                unspecified or NIL, in which case as many digits as possible
  1260. ;;;                are generated, subject to the constraint that there are no
  1261. ;;;                trailing zeroes.
  1262. ;;;     SCALE    - If this parameter is specified or non-NIL, then the number
  1263. ;;;                printed is (* x (expt 10 scale)).  This scaling is exact,
  1264. ;;;                and cannot lose precision.
  1265. ;;;     FMIN     - This parameter, if specified or non-NIL, is the minimum
  1266. ;;;                number of fraction digits which will be produced, regardless
  1267. ;;;                of the value of WIDTH or FDIGITS.  This feature is used by
  1268. ;;;                the ~E format directive to prevent complete loss of
  1269. ;;;                significance in the printed value due to a bogus choice of
  1270. ;;;                scale factor.
  1271. ;;;
  1272. ;;; Most of the optional arguments are for the benefit for FORMAT and are not
  1273. ;;; used by the printer.
  1274. ;;;
  1275. ;;; Returns:
  1276. ;;; (VALUES DIGIT-STRING DIGIT-LENGTH LEADING-POINT TRAILING-POINT DECPNT)
  1277. ;;; where the results have the following interpretation:
  1278. ;;;
  1279. ;;;     DIGIT-STRING    - The decimal representation of X, with decimal point.
  1280. ;;;     DIGIT-LENGTH    - The length of the string DIGIT-STRING.
  1281. ;;;     LEADING-POINT   - True if the first character of DIGIT-STRING is the
  1282. ;;;                       decimal point.
  1283. ;;;     TRAILING-POINT  - True if the last character of DIGIT-STRING is the
  1284. ;;;                       decimal point.
  1285. ;;;     POINT-POS       - The position of the digit preceding the decimal
  1286. ;;;                       point.  Zero indicates point before first digit.
  1287. ;;;
  1288. ;;; WARNING: For efficiency, there is a single string object *digit-string*
  1289. ;;; which is modified destructively and returned as the value of
  1290. ;;; FLONUM-TO-STRING.  Thus the returned value is not valid across multiple 
  1291. ;;; calls.
  1292. ;;;
  1293. ;;; NOTE:  FLONUM-TO-STRING goes to a lot of trouble to guarantee accuracy.
  1294. ;;; Specifically, the decimal number printed is the closest possible 
  1295. ;;; approximation to the true value of the binary number to be printed from 
  1296. ;;; among all decimal representations  with the same number of digits.  In
  1297. ;;; free-format output, i.e. with the number of digits unconstrained, it is 
  1298. ;;; guaranteed that all the information is preserved, so that a properly-
  1299. ;;; rounding reader can reconstruct the original binary number, bit-for-bit, 
  1300. ;;; from its printed decimal representation. Furthermore, only as many digits
  1301. ;;; as necessary to satisfy this condition will be printed.
  1302. ;;;
  1303. ;;;
  1304. ;;; FLOAT-STRING actually generates the digits for positive numbers.  The
  1305. ;;; algorithm is essentially that of algorithm Dragon4 in "How to Print 
  1306. ;;; Floating-Point Numbers Accurately" by Steele and White.  The current 
  1307. ;;; (draft) version of this paper may be found in [CMUC]<steele>tradix.press.
  1308. ;;; DO NOT EVEN THINK OF ATTEMPTING TO UNDERSTAND THIS CODE WITHOUT READING 
  1309. ;;; THE PAPER!
  1310.  
  1311. (defvar *digits* "0123456789")
  1312.  
  1313. (defvar *digit-string*
  1314.   (make-array 50 :element-type 'base-char :fill-pointer 0 :adjustable t
  1315.           :initial-element #\?)) ; ### Hack around make-array bug.
  1316.  
  1317. (defun flonum-to-string (x &optional width fdigits scale fmin)
  1318.   (cond ((zerop x)
  1319.      ;;zero is a special case which float-string cannot handle
  1320.      (if fdigits
  1321.          (let ((s (make-string (1+ fdigits) :initial-element #\0)))
  1322.            (setf (schar s 0) #\.)
  1323.            (values s (length s) t (zerop fdigits) 0))
  1324.          (values "." 1 t t 0)))
  1325.     (t
  1326.      (setf (fill-pointer *digit-string*) 0)
  1327.      (multiple-value-bind (sig exp)
  1328.                   (integer-decode-float x)
  1329.        (let* ((precision (float-precision x))
  1330.           (digits (float-digits x))
  1331.           (fudge (- digits precision))
  1332.           (width (if width (max width 1) nil)))
  1333.        (float-string (ash sig (- fudge)) (+ exp fudge) precision width
  1334.              fdigits scale fmin))))))
  1335.  
  1336.  
  1337. (defun float-string (fraction exponent precision width fdigits scale fmin)
  1338.   (let ((r fraction) (s 1) (m- 1) (m+ 1) (k 0)
  1339.     (digits 0) (decpnt 0) (cutoff nil) (roundup nil) u low high)
  1340.     ;;Represent fraction as r/s, error bounds as m+/s and m-/s.
  1341.     ;;Rational arithmetic avoids loss of precision in subsequent calculations.
  1342.     (cond ((> exponent 0)
  1343.        (setq r (ash fraction exponent))
  1344.        (setq m- (ash 1 exponent))       
  1345.        (setq m+ m-))                   
  1346.       ((< exponent 0)
  1347.        (setq s (ash 1 (- exponent)))))
  1348.     ;;adjust the error bounds m+ and m- for unequal gaps
  1349.     (when (= fraction (ash 1 precision))
  1350.       (setq m+ (ash m+ 1))
  1351.       (setq r (ash r 1))
  1352.       (setq s (ash s 1)))
  1353.     ;;scale value by requested amount, and update error bounds
  1354.     (when scale
  1355.       (if (minusp scale)
  1356.       (let ((scale-factor (expt 10 (- scale))))
  1357.         (setq s (* s scale-factor)))
  1358.       (let ((scale-factor (expt 10 scale)))
  1359.         (setq r (* r scale-factor))
  1360.         (setq m+ (* m+ scale-factor))
  1361.         (setq m- (* m- scale-factor)))))
  1362.     ;;scale r and s and compute initial k, the base 10 logarithm of r
  1363.     (do ()
  1364.         ((>= r (ceiling s 10)))
  1365.       (decf k)
  1366.       (setq r (* r 10))
  1367.       (setq m- (* m- 10))
  1368.       (setq m+ (* m+ 10)))
  1369.     (do ()(nil)
  1370.       (do ()
  1371.       ((< (+ (ash r 1) m+) (ash s 1)))
  1372.     (setq s (* s 10))
  1373.     (incf k))
  1374.       ;;determine number of fraction digits to generate
  1375.       (cond (fdigits
  1376.          ;;use specified number of fraction digits
  1377.          (setq cutoff (- fdigits))
  1378.          ;;don't allow less than fmin fraction digits
  1379.          (if (and fmin (> cutoff (- fmin))) (setq cutoff (- fmin))))
  1380.         (width
  1381.          ;;use as many fraction digits as width will permit
  1382.              ;;but force at least fmin digits even if width will be exceeded
  1383.          (if (< k 0)
  1384.          (setq cutoff (- 1 width))
  1385.          (setq cutoff (1+ (- k width))))
  1386.          (if (and fmin (> cutoff (- fmin))) (setq cutoff (- fmin)))))
  1387.       ;;If we decided to cut off digit generation before precision has
  1388.       ;;been exhausted, rounding the last digit may cause a carry propagation.
  1389.       ;;We can prevent this, preserving left-to-right digit generation, with
  1390.       ;;a few magical adjustments to m- and m+.  Of course, correct rounding
  1391.       ;;is also preserved.
  1392.       (when (or fdigits width)
  1393.     (let ((a (- cutoff k))
  1394.           (y s))
  1395.       (if (>= a 0)
  1396.           (dotimes (i a) (setq y (* y 10)))
  1397.           (dotimes (i (- a)) (setq y (ceiling y 10))))
  1398.       (setq m- (max y m-))
  1399.       (setq m+ (max y m+))
  1400.       (when (= m+ y) (setq roundup t))))
  1401.       (when (< (+ (ash r 1) m+) (ash s 1)) (return)))
  1402.     ;;zero-fill before fraction if no integer part
  1403.     (when (< k 0)
  1404.       (setq decpnt digits)
  1405.       (vector-push-extend #\. *digit-string*)
  1406.       (dotimes (i (- k))
  1407.     (incf digits) (vector-push-extend #\0 *digit-string*)))
  1408.     ;;generate the significant digits
  1409.     (do ()(nil)
  1410.       (decf k)
  1411.       (when (= k -1)
  1412.     (vector-push-extend #\. *digit-string*)
  1413.     (setq decpnt digits))
  1414.       (multiple-value-setq (u r) (truncate (* r 10) s))
  1415.       (setq m- (* m- 10))
  1416.       (setq m+ (* m+ 10))
  1417.       (setq low (< (ash r 1) m-))
  1418.       (if roundup
  1419.       (setq high (>= (ash r 1) (- (ash s 1) m+)))
  1420.       (setq high (> (ash r 1) (- (ash s 1) m+))))
  1421.       ;;stop when either precision is exhausted or we have printed as many
  1422.       ;;fraction digits as permitted
  1423.       (when (or low high (and cutoff (<= k cutoff))) (return))
  1424.       (vector-push-extend (char *digits* u) *digit-string*)
  1425.       (incf digits))
  1426.     ;;if cutoff occured before first digit, then no digits generated at all
  1427.     (when (or (not cutoff) (>= k cutoff))
  1428.       ;;last digit may need rounding
  1429.       (vector-push-extend (char *digits*
  1430.                 (cond ((and low (not high)) u)
  1431.                       ((and high (not low)) (1+ u))
  1432.                       (t (if (<= (ash r 1) s) u (1+ u)))))
  1433.               *digit-string*)
  1434.       (incf digits))
  1435.     ;;zero-fill after integer part if no fraction
  1436.     (when (>= k 0)
  1437.       (dotimes (i k) (incf digits) (vector-push-extend #\0 *digit-string*))
  1438.       (vector-push-extend #\. *digit-string*)
  1439.       (setq decpnt digits))
  1440.     ;;add trailing zeroes to pad fraction if fdigits specified
  1441.     (when fdigits
  1442.       (dotimes (i (- fdigits (- digits decpnt)))
  1443.     (incf digits)
  1444.     (vector-push-extend #\0 *digit-string*)))
  1445.     ;;all done
  1446.     (values *digit-string* (1+ digits) (= decpnt 0) (= decpnt digits) decpnt)))
  1447.  
  1448. ;;; SCALE-EXPONENT  --  Internal
  1449. ;;;
  1450. ;;;    Given a non-negative floating point number, SCALE-EXPONENT returns a new
  1451. ;;; floating point number Z in the range (0.1, 1.0] and and exponent E such
  1452. ;;; that Z * 10^E is (approximately) equal to the original number.  There may
  1453. ;;; be some loss of precision due the floating point representation.  The
  1454. ;;; scaling is always done with long float arithmetic, which helps printing of
  1455. ;;; lesser precisions as well as avoiding generic arithmetic.
  1456. ;;;
  1457. ;;;    When computing our initial scale factor using EXPT, we pull out part of
  1458. ;;; the computation to avoid over/under flow.  When denormalized, we must pull
  1459. ;;; out a large factor, since there is more negative exponent range than
  1460. ;;; positive range.
  1461. ;;;
  1462. (defun scale-exponent (original-x)
  1463.   (let* ((x (coerce original-x 'long-float)))
  1464.     (multiple-value-bind (sig exponent)
  1465.              (decode-float x)
  1466.       (declare (ignore sig))
  1467.       (if (= x 0.0l0)
  1468.       (values (float 0.0l0 original-x) 1)
  1469.       (let* ((ex (round (* exponent (log 2l0 10))))
  1470.          (x (if (minusp ex)
  1471.             (if (float-denormalized-p x)
  1472.                 (* x 1.0l16 (expt 10.0l0 (- (- ex) 16)))
  1473.                 (* x 10.0l0 (expt 10.0l0 (- (- ex) 1))))
  1474.             (/ x 10.0l0 (expt 10.0l0 (1- ex))))))
  1475.         (do ((d 10.0l0 (* d 10.0l0))
  1476.          (y x (/ x d))
  1477.          (ex ex (1+ ex)))
  1478.         ((< y 1.0l0)
  1479.          (do ((m 10.0l0 (* m 10.0l0))
  1480.               (z y (* y m))
  1481.               (ex ex (1- ex)))
  1482.              ((>= z 0.1l0)
  1483.               (values (float z original-x) ex))))))))))
  1484.  
  1485.  
  1486. ;;;; Entry point for the float printer.
  1487.  
  1488. ;;; Entry point for the float printer as called by PRINT, PRIN1, PRINC,
  1489. ;;; etc.  The argument is printed free-format, in either exponential or 
  1490. ;;; non-exponential notation, depending on its magnitude.
  1491. ;;;
  1492. ;;; NOTE: When a number is to be printed in exponential format, it is scaled in
  1493. ;;; floating point.  Since precision may be lost in this process, the
  1494. ;;; guaranteed accuracy properties of FLONUM-TO-STRING are lost.  The
  1495. ;;; difficulty is that FLONUM-TO-STRING performs extensive computations with
  1496. ;;; integers of similar magnitude to that of the number being printed.  For
  1497. ;;; large exponents, the bignums really get out of hand.  If bignum arithmetic
  1498. ;;; becomes reasonably fast and the exponent range is not too large, then it
  1499. ;;; might become attractive to handle exponential notation with the same
  1500. ;;; accuracy as non-exponential notation, using the method described in the
  1501. ;;; Steele and White paper.
  1502.  
  1503.  
  1504. ;;; PRINT-FLOAT-EXPONENT  --  Internal
  1505. ;;;
  1506. ;;;    Print the appropriate exponent marker for X and the specified exponent.
  1507. ;;;
  1508. (defun print-float-exponent (x exp stream)
  1509.   (declare (float x) (integer exp) (stream stream))
  1510.   (let ((*print-radix* nil)
  1511.     (plusp (plusp exp)))
  1512.     (if (typep x *read-default-float-format*)
  1513.     (unless (eql exp 0)
  1514.       (format stream "e~:[~;+~]~D" plusp exp))
  1515.     (format stream "~A~:[~;+~]~D" 
  1516.         (etypecase x
  1517.           (single-float #\f)
  1518.           (double-float #\d)
  1519.           (short-float #\s)
  1520.           (long-float #\L))
  1521.         plusp exp))))
  1522.  
  1523.  
  1524. ;;; FLOAT-FORMAT-NAME  --  Internal
  1525. ;;;
  1526. ;;;    Return the string name of X's float format.
  1527. ;;;
  1528. (defun float-format-name (x)
  1529.   (declare (float x))
  1530.   (etypecase x
  1531.     (single-float "SINGLE-FLOAT")
  1532.     (double-float "DOUBLE-FLOAT")
  1533.     (short-float "SHORT-FLOAT")
  1534.     (long-float "LONG-FLOAT")))
  1535.  
  1536.  
  1537. ;;; OUTPUT-FLOAT-INFINITY  --  Internal
  1538. ;;;
  1539. ;;;    Write out an infinity using #. notation, or flame out if
  1540. ;;; *print-readably* is true and *read-eval* is false.
  1541. ;;;
  1542. (defun output-float-infinity (x stream)
  1543.   (declare (float x) (stream stream))
  1544.   (cond (*read-eval*
  1545.      (write-string "#." stream))
  1546.     (*print-readably*
  1547.      (error "Unable to print infinities readably without #."))
  1548.     (t
  1549.      (write-string "#<" stream)))
  1550.   (write-string "EXT:" stream)
  1551.   (write-string (float-format-name x) stream)
  1552.   (write-string (if (plusp x) "-POSITIVE-" "-NEGATIVE-")
  1553.         stream)
  1554.   (write-string "INFINITY" stream)
  1555.   (unless *read-eval*
  1556.     (write-string ">" stream)))
  1557.  
  1558.  
  1559. ;;; OUTPUT-FLOAT-NAN  --  Internal
  1560. ;;;
  1561. ;;;    Output a #< NaN or die trying.
  1562. ;;;
  1563. (defun output-float-nan (x stream)
  1564.   (when *print-readably*
  1565.     (error "Can't print NaN's readably."))
  1566.   (write-string "#<" stream)
  1567.   (write-string (float-format-name x) stream)
  1568.   (write-string (if (float-trapping-nan-p x) " Trapping" " Quiet") stream)
  1569.   (write-string " NaN>" stream))
  1570.  
  1571.  
  1572. ;;; OUTPUT-FLOAT  --  Internal
  1573. ;;;
  1574. ;;;    Functioned called by OUTPUT-OBJECT to handle floats.
  1575. ;;;
  1576. (defun output-float (x stream)
  1577.   (cond
  1578.    ((float-infinity-p x)
  1579.     (output-float-infinity x stream))
  1580.    ((float-nan-p x)
  1581.     (output-float-nan x stream))
  1582.    (t
  1583.     (let ((x (cond ((minusp (float-sign x))
  1584.             (write-char #\- stream)
  1585.             (- x))
  1586.            (t
  1587.             x))))
  1588.       (cond
  1589.        ((zerop x)
  1590.     (write-string "0.0" stream)
  1591.     (print-float-exponent x 0 stream))
  1592.        (t
  1593.     (output-float-aux x stream (float 1/1000 x) (float 10000000 x))))))))
  1594. ;;;  
  1595. (defun output-float-aux (x stream e-min e-max)
  1596.   (if (and (>= x e-min) (< x e-max))
  1597.       ;;free format
  1598.       (multiple-value-bind (str len lpoint tpoint)
  1599.                (flonum-to-string x)
  1600.     (declare (ignore len))
  1601.     (when lpoint (write-char #\0 stream))
  1602.     (write-string str stream)
  1603.     (when tpoint (write-char #\0 stream))
  1604.     (print-float-exponent x 0 stream))
  1605.       ;;exponential format 
  1606.       (multiple-value-bind (f ex)
  1607.                (scale-exponent x)
  1608.     (multiple-value-bind (str len lpoint tpoint)
  1609.                  (flonum-to-string f nil nil 1)
  1610.       (declare (ignore len))
  1611.       (when lpoint (write-char #\0 stream))
  1612.       (write-string str stream)
  1613.       (when tpoint (write-char #\0 stream))
  1614.       ;; subtract out scale factor of 1 passed to flonum-to-string
  1615.       (print-float-exponent x (1- ex) stream)))))
  1616.  
  1617.  
  1618. ;;;; Other leaf objects.
  1619.  
  1620. ;;; OUTPUT-CHARACTER  --  Internal
  1621. ;;;
  1622. ;;;    If *print-escape* is false, just do a WRITE-CHAR, otherwise output the
  1623. ;;; character name or the character in the #\char format.
  1624. ;;;
  1625. (defun output-character (char stream)
  1626.   (if (or *print-escape* *print-readably*)
  1627.       (let ((name (char-name char)))
  1628.     (write-string "#\\" stream)
  1629.     (if name
  1630.         (write-string name stream)
  1631.         (write-char char stream)))
  1632.       (write-char char stream)))
  1633.  
  1634. (defun output-sap (sap stream)
  1635.   (declare (type system-area-pointer sap))
  1636.   (cond (*read-eval*
  1637.      (format stream "#.(~S #x~8,'0X)"
  1638.          'int-sap (sap-int sap)))
  1639.     ((not *print-readably*)
  1640.      (format stream "#<System-Area-Pointer: #x~8,'0X>"
  1641.          (sap-int sap)))
  1642.     (t
  1643.      (error "Cannot print system-area-pointers with *READ-EVAL* NIL and ~
  1644.          *PRINT-READABLY* T."))))
  1645.  
  1646. (defun output-weak-pointer (weak-pointer stream)
  1647.   (declare (type weak-pointer weak-pointer))
  1648.   (when *print-readably*
  1649.     (error "Cannot print weak poinrts with *PRINT-READABLY* T."))
  1650.   (multiple-value-bind
  1651.       (value validp)
  1652.       (weak-pointer-value weak-pointer)
  1653.     (cond (validp
  1654.        (write-string "#<Weak Pointer: " stream)
  1655.        (write value :stream stream)
  1656.        (write-char #\> stream))
  1657.       (t
  1658.        (write-string "#<Broken Weak Pointer>" stream)))))
  1659.  
  1660. (defun output-code-component (component stream)
  1661.   (print-unreadable-object (component stream :identity t)
  1662.     (let ((dinfo (code-header-ref component vm:code-debug-info-slot)))
  1663.       (cond ((eq dinfo :bogus-lra)
  1664.          (write-string "Bogus Code Object" stream))
  1665.         (t
  1666.          (write-string "Code Object" stream)
  1667.          (when dinfo
  1668.            (write-char #\space stream)
  1669.            (output-object (c::compiled-debug-info-name dinfo) stream)))))))
  1670.  
  1671. (defun output-lra (lra stream)
  1672.   (print-unreadable-object (lra stream :identity t)
  1673.     (write-string "Return PC Object" stream)))
  1674.  
  1675. (defun output-fdefn (fdefn stream)
  1676.   (print-unreadable-object (fdefn stream)
  1677.     (write-string "FDEFINITION object for " stream)
  1678.     (output-object (fdefn-name fdefn) stream)))
  1679.  
  1680.  
  1681.  
  1682. ;;;; Various flavors of function pointers.
  1683.  
  1684.  
  1685. ;;; OUTPUT-FUNCTION-OBJECT outputs the main part of the printed 
  1686. ;;; representation of function objects.  It is called from OUTPUT-RANDOM
  1687. ;;; below.
  1688.  
  1689. (defun output-function-object (subr stream)
  1690.   (let ((name (%primitive c::function-name subr)))
  1691.     (write-string "Function " stream)
  1692.     (prin1 name stream)))
  1693.  
  1694.  
  1695. ;;; OUTPUT-INTERPRETED-FUNCTION  --  Internal
  1696. ;;;
  1697. ;;;    Print the name or definition of an interpreted function.
  1698. ;;;
  1699. (defun output-interpreted-function (subr stream)
  1700.   (multiple-value-bind
  1701.       (def ignore name)
  1702.       (eval:interpreted-function-lambda-expression subr)
  1703.     (declare (ignore ignore))
  1704.     (let ((*print-level* 3))
  1705.       (format stream "Interpreted Function ~S" (or name def)))))
  1706.  
  1707. (defun output-function (function stream)
  1708.   (print-unreadable-object (function stream :identity t)
  1709.     (case (get-type function)
  1710.       ((#.vm:function-header-type #.vm:closure-function-header-type)
  1711.        (output-function-object function stream))
  1712.       (#.vm:closure-header-type
  1713.        (cond
  1714.     ((eval:interpreted-function-p function)
  1715.      (output-interpreted-function function stream))
  1716.     (t
  1717.      (write-string "Closure Over " stream)
  1718.      (output-function-object (%primitive c::closure-function function)
  1719.                  stream)))))))
  1720.     
  1721.  
  1722.  
  1723. ;;;; Catch-all for unknown things.
  1724.  
  1725. (defun output-random (object stream)
  1726.   (print-unreadable-object (object stream :identity t)
  1727.     (let ((lowtag (get-lowtag object)))
  1728.       (case lowtag
  1729.     (#.vm:other-pointer-type
  1730.       (let ((type (get-type object)))
  1731.         (case type
  1732.           (#.vm:value-cell-header-type
  1733.            (write-string "Value Cell " stream)
  1734.            (output-object (%primitive value-cell-ref object) stream))
  1735.           (t
  1736.            (write-string "Unknown Pointer Object, type=" stream)
  1737.            (let ((*print-base* 16) (*print-radix* t))
  1738.          (output-integer type stream))))))
  1739.     ((#.vm:function-pointer-type
  1740.       #.vm:structure-pointer-type
  1741.       #.vm:list-pointer-type)
  1742.      (write-string "Unknown Pointer Object, type=" stream))
  1743.     (t
  1744.      (case (get-type object)
  1745.        (#.vm:unbound-marker-type
  1746.         (write-string "Unbound Marker" stream))
  1747.        (t
  1748.         (write-string "Unknown Immediate Object, lowtag=" stream)
  1749.         (let ((*print-base* 2) (*print-radix* t))
  1750.           (output-integer lowtag stream))
  1751.         (write-string ", type=" stream)
  1752.         (let ((*print-base* 16) (*print-radix* t))
  1753.           (output-integer (get-type object) stream)))))))))
  1754.